package org.zfin.properties.ant;

import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.log4j.Logger;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;

/**
 * Arguments:
 * - propertyFile (required)
 * - enumClass (required)
 * - sourceDir (optional: default ./)
 * - override  (optional: default is true)
 */
public class CreateEnumTask extends PropertyFileTask {

    private String sourceDir = ".";
    private final static Logger logger = Logger.getLogger(CreateEnumTask.class) ;

    public void execute() {
        BufferedWriter bufferedWriter = null ;
        try {
            logger.debug("Creating enum file: "  +getFullFilePath());
            logger.debug("From property file: "  + getFile());
            PropertiesConfiguration propertiesConfiguration = createPropertiesConfiguration();

            File file = new File(getFullFilePath()) ;
            logger.debug("Enum file created: " + file.getAbsolutePath());
            if(file.exists()){
                assert(file.delete());
            }

            bufferedWriter = new BufferedWriter(new FileWriter(file)) ;
            // write prefix
            bufferedWriter.write("package "+getPackage() +";\n\n");
            bufferedWriter.write("import "+ this.getClass().getPackage().getName() +".*;\n\n");
            bufferedWriter.write("/**\nGenerated by "+this.getClass().getCanonicalName()+"\n**/\n");
            bufferedWriter.write("public enum "+getEnumName()+" implements SettableEnum{\n");

            String key ;
            for(Iterator iterator = propertiesConfiguration.getKeys();
                iterator.hasNext(); ){
                key = iterator.next().toString();
                bufferedWriter.write(key+",\n");
            }
            bufferedWriter.write(";\n");

            bufferedWriter.write("private String value;\n");
            bufferedWriter.write("private "+getEnumName()+"(String value){this.value=value;}\n");
            bufferedWriter.write("private "+getEnumName()+"(){this(null);}\n");
            bufferedWriter.write("public String value(){return this.value;}\n");
            bufferedWriter.write("public String toString(){return this.value;}\n");
            bufferedWriter.write("public void setValue(String value){this.value=value;}\n");

            bufferedWriter.write("public static "+ getEnumName() + " getEnumByName(String name){\n" +
                    "for("+getEnumName()+" t : values()){\n" +
                    "if(t.toString().equals(name.trim())){\n" +
                    "return t;\n" +
                    "}}\n" +
                    "throw new RuntimeException(\"No enum of name \" + name + \" found.\");\n" +
                    "}");
            bufferedWriter.write("}\n");
            bufferedWriter.close();

        } catch (Exception e) {
            throw new RuntimeException("failed to load configuration",e);
        }
        finally{
            try {
                if(bufferedWriter!=null){
                    bufferedWriter.close();
                }
            } catch (IOException e) {
                logger.error(e);
            }
        }
    }


    public void setSourceDir(String sourceDir) {
        this.sourceDir = sourceDir;
    }

    public String getFullFilePath(){
        return sourceDir + "/" + getEnumClass().replaceAll("\\.","/")+".java" ;
    }

    protected String getPackage() {
        return getEnumClass().substring(0, getEnumClass().lastIndexOf("."));
    }

    public String getEnumName() {
        return getEnumClass().substring(getEnumClass().lastIndexOf(".")+1);
    }
}